package com.wfcm.controller;

import com.alibaba.fastjson.JSONObject;
import com.google.gson.Gson;
import com.wfcm.entity.*;
import com.wfcm.service.IapService;
import com.wfcm.service.WfMemberGiveCoinLogService;
import com.wfcm.service.WfMemberNewGoldLogService;
import com.wfcm.service.WfMemberRechargeOrderService;
import com.wfcm.utils.DateUtil;
import com.wfcm.utils.ISsoLoginHelper;
import com.wfcm.utils.R;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import javax.net.ssl.HttpsURLConnection;
import javax.net.ssl.SSLContext;
import javax.net.ssl.TrustManager;
import javax.net.ssl.X509TrustManager;
import javax.servlet.http.HttpServletRequest;
import java.io.BufferedOutputStream;
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.math.BigDecimal;
import java.net.URL;
import java.security.cert.CertificateException;
import java.security.cert.X509Certificate;
import java.util.Date;

@RestController
@RequestMapping("new-iap")
public class NewIapController {

    private static Logger logger = LoggerFactory.getLogger(NewIapController.class);

    @Autowired
    private IapService iapService;
    @Autowired
    private WfMemberGiveCoinLogService memberGiveCoinLogService;
    @Autowired
    private WfMemberNewGoldLogService memberNewGoldLogService;
    @Autowired
    private WfMemberRechargeOrderService memberRechargeOrderService;

    private static final String verifyReceiptUrl = "https://buy.itunes.apple.com/verifyReceipt";

    private static final String verifyReceiptTestUrl = "https://sandbox.itunes.apple.com/verifyReceipt";

    private static TrustManager myX509TrustManager = new X509TrustManager() {

        @Override
        public X509Certificate[] getAcceptedIssuers() {
            return null;
        }

        @Override
        public void checkServerTrusted(X509Certificate[] chain, String authType) throws CertificateException {

        }

        @Override
        public void checkClientTrusted(X509Certificate[] chain, String authType) throws CertificateException {

        }
    };

    private String sendHttpsConnection(String url, String receipt) {
        String content = null;
        try {
            SSLContext ssl = SSLContext.getInstance("SSL");
            ssl.init(null, new TrustManager[]{myX509TrustManager}, null);

            HttpsURLConnection conn = (HttpsURLConnection) new URL(url).openConnection();
            conn.setSSLSocketFactory(ssl.getSocketFactory());
            conn.setRequestProperty("Content-type", "application/json");
            conn.setRequestMethod("POST");
            conn.setDoInput(true);
            conn.setDoOutput(true);

            JSONObject obj = new JSONObject();
            obj.put("receipt-data", receipt);
            BufferedOutputStream bos = new BufferedOutputStream(conn.getOutputStream());
            bos.write(obj.toString().getBytes());
            bos.flush();
            bos.close();
            BufferedReader br = new BufferedReader(new InputStreamReader(conn.getInputStream()));
            String line;
            StringBuffer sb = new StringBuffer();
            while ((line = br.readLine()) != null) {
                sb.append(line);
            }
            br.close();
            content = sb.toString();
        } catch (Exception e) {
            logger.error(e.getMessage(), e);
        }
        return content;
    }

    /**
     * ios商品列表
     *
     * @return
     */
    @RequestMapping("productionList")
    public R productionList(HttpServletRequest req) {
        R r = R.ok();
        try {
            r.put("results", iapService.productionList(req.getHeader("version")));
        } catch (Exception e) {
            r = R.error(500, "服务器异常！");
            logger.error(e.getMessage(), e);
        }
        return r;
    }

    /**
     * 校验用户购买凭证
     *
     * @param iapParam
     * @param req
     * @return
     */
    @RequestMapping("/verifyReceipt")
    public R verifyReceipt(@RequestBody IapParam iapParam, HttpServletRequest req) {
        R r;
        Integer userId = ISsoLoginHelper.confirm(req);
        try {
            // 判断是否已充值过
            if (iapService.queryVerifyReceiptLog(iapParam.getTransactionId())) {
                String result = sendHttpsConnection(iapParam.getEnvironment().equals(1)
                        ? verifyReceiptUrl : verifyReceiptTestUrl, iapParam.getReceipt());
                logger.error("Ios verifyReceipt - " + result);
                Iap iap = new Gson().fromJson(result, Iap.class);
                if (iap.getStatus().equals(21007)) {
                    iapParam.setEnvironment(2);
                }
                if (!iap.getStatus().equals(0)) {
                    if (!iap.getStatus().equals(21007)) {
                        Thread.sleep(5000);
                    }
                    result = sendHttpsConnection(iapParam.getEnvironment().equals(1)
                            ? verifyReceiptUrl : verifyReceiptTestUrl, iapParam.getReceipt());
                    iap = new Gson().fromJson(result, Iap.class);
                    if (!iap.getStatus().equals(0)) {
                        Thread.sleep(5000);
                        result = sendHttpsConnection(iapParam.getEnvironment().equals(1)
                                ? verifyReceiptUrl : verifyReceiptTestUrl, iapParam.getReceipt());
                        iap = new Gson().fromJson(result, Iap.class);
                    }
                }
                r = R.error(iap.getStatus(), "");
                iapService.addVerifyReceiptLog(new IapParam(userId, iap.getStatus(),
                        iapParam.getTransactionId(), new Gson().toJson(iapParam), result));
                // 判断凭证在苹果服务器是否支付成功
                if (iap.getStatus().equals(0)) {
                    iap.getReceipt().getIn_app().forEach(item -> {
                        // 判断交易ID能否对应
                        if (item.getTransaction_id().equals(iapParam.getTransactionId())) {
                            String orderNum = DateUtil.getRechargeOrderNum();
                            IapProduction production = iapService.queryProduction(item.getProduct_id());
                            memberNewGoldLogService.save(new WfMemberNewGoldLogEntity(userId,
                                    production.getPrice(), orderNum, iapParam.getEnvironment()));
                            memberRechargeOrderService.save(new WfMemberRechargeOrderEntity(userId, production.getPrice(),
                                    production.getRebate(), orderNum, iapParam.getTransactionId(), iapParam.getEnvironment()));
                            // 判断是否有充值赠送
                            if (production.getRebate() != null && production.getRebate() > 0) {
                                memberGiveCoinLogService.save(new WfMemberGiveCoinLogEntity(userId, production.getRebate(), orderNum));
                            }
                        }
                    });
                }
            } else {
                r = R.error(0, "");
            }
        } catch (Exception e) {
            iapService.addVerifyReceiptLog(new IapParam(userId, 500,
                    iapParam.getTransactionId(), new Gson().toJson(iapParam), e.getMessage()));
            r = R.error(500, "");
            logger.error(e.getMessage(), e);
        }
        return r;
    }
}
